﻿

using IotClientService.Handles;
using IotClientService.Handles.lgs;
using IotClientService.Models.Lg;
using IotContract.Dtos.Clients.Equips;
using IotContract.Dtos.Servers;
using IotContract.Events;
using IotContract.Interfaces;
using IotContract.Models.Clients;
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using XT.Common.Extensions;
using XT.Common.Services;
using XT.MNet.Tcp;

namespace IotClientService.Operations.MNet;
public class LgNetOperation : IEquipOperation<LgNetEquipDto>
{
    public event EventHandler<ConnectStatusEventArgs> OnConnectStatusChanged;

    private IServiceProvider _provider;
    private CancellationTokenSource _cancellationTokenSource;
    private ILogService _logService;

    private bool _status = false;
    private LgTcpState _tcpState = LgTcpState.Closed;

    private LgHkEquipDto _equipInfo;
    private LgHandleBase _lgEquipHandle;
   

    private TcpServer _sendServer;

    private TcpServer _recieveServer;
    public LgNetOperation(IServiceProvider provider, ILogService logService)
    {
        _provider=provider;
        _logService = logService;
    }
    public void Dispose()
    {
        return;
    }
    /// <summary>
    /// 获取连接状态
    /// </summary>
    /// <returns></returns>
    public bool GetConnection()
    {
        return _tcpState == LgTcpState.Connected ;
    }
    /// <summary>
    /// 获取设备信息
    /// </summary>
    /// <returns></returns>
    public LgNetEquipDto GetEquipInfo()
    {
        return _equipInfo.Adapt<LgNetEquipDto>();
    }
    /// <summary>
    /// 获取操作状态
    /// </summary>
    /// <returns></returns>
    public bool GetOperationStatus()
    {
        return _status;
    }
    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="group"></param>
    /// <param name="tags"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<bool> Init(LgNetEquipDto group, IEnumerable<EquipTagDto> tags = null)
    {
        try
        {
            _equipInfo = group.Adapt<LgHkEquipDto>();
            // 解析ipaddress
            var ips = group.IPAddress.Split(":");
            if (ips.Length != 2)
            {
                return false;
            }

            var sendPort = group.ReadDirection.To<int>();
            if (sendPort == 0)
            {
                return false;
            }
            // 获取设备对应的处理器
            _lgEquipHandle = _provider.GetRequiredKeyedService<LgHandleBase>(_equipInfo.EquipType);
            // 设定API访问URL
            _lgEquipHandle.Api.RemoteApiUrl = _provider.GetService<IConnectDataService>()?.AddressConfig.ApiUrl;
            _lgEquipHandle.Equip = _equipInfo;
            if (_lgEquipHandle != null)
            {
                _lgEquipHandle.SendMsgEvent -= Handle_SendMsgEvent;
                _lgEquipHandle.SendMsgEvent += Handle_SendMsgEvent;
            }
        }
        catch (Exception ex)
        {
            _equipInfo.Remark = $"Error Initial,Exception：{ex.Message}";
            OnConnectStatusChanged.Invoke(this, new ConnectStatusEventArgs
            {
                Connect = false,
                IsSuccess = true,
                Message = _equipInfo.Remark
            });
            return false;
        }

        return true;
    }
    /// <summary>
    /// 需要发送数据给设备
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private  void Handle_SendMsgEvent(object? sender, (LgMsgInfo, LgHkEquipDto) e)
    {
        _equipInfo.Value = $"command:{e.Item1.Command} status:{e.Item2.EquipStatus} obj:{e.Item2.Obj}";


        _equipInfo.EquipStatus = e.Item2.EquipStatus;

        _equipInfo.Action = e.Item2.Action;

        _equipInfo.Mode = e.Item2.Mode;

        _equipInfo.ExplainData = e.Item2.ExplainData;

        _equipInfo.ReadTime = e.Item2.ReadTime;
        // 不发送直接退出
        if (!e.Item1.IsSend) return;
        if (_tcpState == LgTcpState.Connected)
        {       // 组装数据
                var msg = _lgEquipHandle.AssambleMsg(e.Item1);
                var sendData=Encoding.UTF8.GetBytes(msg);
                
                _sendServer.Broadcast(sendData);
            
                _logService.LogHeart($"{e.Item2.Num}  send over: {e.Item1.Command}: {msg}");
        }
    }
    /// <summary>
    /// 启动
    /// </summary>
    /// <returns></returns>
    public async Task<bool> OperationStart()
    {
        try
        {
           
            var ips = _equipInfo.IPAddress.Split(":");
            _status = true;
            // 发送服务
            _sendServer = new TcpServer(new XT.MNet.Tcp.Options.TcpServerOptions { Address = ips[0], Port = ips[1].To<ushort>() });
            _sendServer.OnConnect += _sendServer_OnConnect;
            _sendServer.OnDisconnect += _sendServer_OnDisconnect;

            // 接收服务
            _recieveServer = new TcpServer(new XT.MNet.Tcp.Options.TcpServerOptions { Address = ips[0], Port = _equipInfo.ReadDirection.To<ushort>(), SpecialChar = '\u0003' });
            _recieveServer.OnConnect += _recieveServer_OnConnect;
            _recieveServer.OnDisconnect += _recieveServer_OnDisconnect;

            // 订阅数据
            _recieveServer.On(async (data, conn) =>
            {
               
                string recieve = Encoding.UTF8.GetString(data.ToArray());
                _logService.LogHeart($"{_equipInfo.Num} recieve {recieve}");

               await _lgEquipHandle.HandleData(recieve, _equipInfo);

                _logService.LogHeart($"{_equipInfo.Num} handle recieve over");
            });


            _sendServer.Start();

            _recieveServer.Start();


            _tcpState = LgTcpState.Listening;
            _equipInfo.Remark = _tcpState.ToString();
            OnConnectStatusChanged.Invoke(this, new ConnectStatusEventArgs
            {
                Connect = false,
                IsSuccess = true,
                Message = _equipInfo.Remark
            });
        }
        catch(Exception ex)
        {
            _equipInfo.Remark = $"Error Start,Exception：{ex.Message}";
            OnConnectStatusChanged.Invoke(this, new ConnectStatusEventArgs
            {
                Connect = false,
                IsSuccess = true,
                Message = _equipInfo.Remark
            });
            return false;
        }

        return true;
    }

    private void _recieveServer_OnDisconnect(TcpServerConnection connection)
    {
        _tcpState = LgTcpState.Connecting;
        _equipInfo.Remark = _tcpState.ToString();
    }

    private void _recieveServer_OnConnect(TcpServerConnection connection)
    {
        _tcpState = LgTcpState.Connected;
        _equipInfo.Remark = _tcpState.ToString();
    }

    private void _sendServer_OnDisconnect(TcpServerConnection connection)
    {
        _tcpState = LgTcpState.Connecting;
        _equipInfo.Remark = _tcpState.ToString();
        CancelPolling();
    }
    /// <summary>
    /// 发送服务连接
    /// </summary>
    /// <param name="connection"></param>
    private async void _sendServer_OnConnect(TcpServerConnection connection)
    {
        _tcpState = LgTcpState.Connected;
        _equipInfo.Remark = _tcpState.ToString();
        CancelPolling();
        _cancellationTokenSource = new CancellationTokenSource();
        await StartPollingAsync(_cancellationTokenSource.Token);
    }

    private void CancelPolling()
    {
        if (_cancellationTokenSource != null)
        {
            _cancellationTokenSource.Cancel();
            _cancellationTokenSource.Dispose();
            _cancellationTokenSource = null;
        }
    }
    /// <summary>
    /// 轮询发送同步信号
    /// </summary>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    private async Task StartPollingAsync(CancellationToken cancellationToken)
    {
        try
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                if (_tcpState == LgTcpState.Connected)
                {
                    _lgEquipHandle.SyncStatus(new LgMsgInfo { ObjID = "AA00001" });
                }
                await Task.Delay(60000, cancellationToken);
            }
        }
        catch (TaskCanceledException)
        {
            // Task was canceled, handle if necessary
        }
        catch (Exception)
        {
            // Log or handle the exception as needed
        }
    }
    /// <summary>
    /// 停止监听
    /// </summary>
    /// <returns></returns>
    public async Task<bool> OperationStop()
    {
        CancelPolling();
        _status = false;
        _recieveServer?.Stop();
        _sendServer?.Stop();
        _tcpState= LgTcpState.Closed;
        _equipInfo.Remark = string.Empty;
        // 刷新推送的数据
        OnConnectStatusChanged.Invoke(this, new ConnectStatusEventArgs
        {
            Connect = false,
            IsSuccess = true,
        });
        return true;
    }
    /// <summary>
    /// 主动写入设备
    /// </summary>
    /// <param name="writeInfo"></param>
    /// <returns></returns>
    public async Task<bool> WriteRequest(OperationWriteCommand writeInfo)
    {

        if (writeInfo.Value.IsNullOrEmpty()) return true;
        var datas = writeInfo.Value.Split('*');
        if (datas.Length > 1)
        {
            var command = datas[0];
            var body = datas[1];

            if (command == "133")
            {
                _lgEquipHandle.ReStart(new LgMsgInfo
                {
                    Body = body

                });
            }
            else if (command == "129")
            {
                _lgEquipHandle.Stop(new LgMsgInfo
                {
                    Body = body
                });
            }
        }
        return true;
    }
}
